  
  
/*  
* Copyright @ 2017 com.iflysse.trains  
* xebest-erp 下午7:44:01  
* All right reserved.  
*  
*/  
  
package com.xebest.web.service.impl;  

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSON;
import com.xebest.common.enums.erp.storehouse.VenStoreDeliveryTypeEnum;
import com.xebest.util.BigDecimalUtil;
import com.xebest.util.seq.StoreHouseSeqUtil;
import com.xebest.web.mapper.read.XeVenStoreDelivDetailReadMapper;
import com.xebest.web.mapper.read.XeVenStoreDeliveryReadMapper;
import com.xebest.web.mapper.write.XeVenStoreDelivDetailWriteMapper;
import com.xebest.web.mapper.write.XeVenStoreDeliveryWriteMapper;
import com.xebest.web.mapper.write.XeVenStoreInventoryDetailWriteMapper;
import com.xebest.web.mapper.write.XeVenStoreInventoryWriteMapper;
import com.xebest.web.mapper.write.XeVenStoreStockWriteMapper;
import com.xebest.web.model.StoreDeliveryForm;
import com.xebest.web.model.XeVenStoreDelivDetailEntity;
import com.xebest.web.model.XeVenStoreDeliveryEntity;
import com.xebest.web.model.XeVenStoreInventoryDetailEntity;
import com.xebest.web.model.XeVenStoreInventoryEntity;
import com.xebest.web.model.XeVenStoreStockEntity;
import com.xebest.web.service.XeVenStoreDelivService;
import com.xebest.web.service.XeVenStoreInventoryService;
import com.xebest.web.view.XeVenDelivDetailView;
import com.xebest.web.view.XeVenStoreDelivView;

  
/** 
 * 出库相关业务类 
 * @desc: xebest-erp  
 * @author: 杜春静 
 * @createTime: 2017年7月3日 下午7:44:01  
 * @history:  
 * @version: v1.0    
*/  
@Service  
public class XeVenStoreDelivServiceImpl implements XeVenStoreDelivService {
	
	private static final Logger log = LoggerFactory.getLogger(XeVenStoreDelivService.class);//日志记录类
	
	@Autowired
	XeVenStoreDelivDetailReadMapper delivDetailReadMapper;//出库商品明细读
	
	@Autowired
	XeVenStoreDelivDetailWriteMapper  delivDetailWriteMapper;//出库商品明细写
	
	@Autowired
	XeVenStoreDeliveryWriteMapper deliveryWriteMapper;//出库单写
	
	
	@Autowired
	XeVenStoreDeliveryReadMapper deliveryReadMapper;//出库单读
	@Autowired
	XeVenStoreInventoryDetailWriteMapper invDtailWriteMapper;//库存一览明细写
	@Autowired
	XeVenStoreStockWriteMapper storeStockWriteMapper;//备货表
	@Autowired
	XeVenStoreInventoryService storeInventoryService;//库存一览的业务类
	@Autowired
	XeVenStoreInventoryWriteMapper xeVenStoreInventoryWriteMapper;
	  
	/*
	 * 查询出库单列表  
	 *(non-Javadoc)  
	 * @see com.xebest.web.service.XeVenStoreDelivService#listDelivByParam(java.util.Map)  
	*/  
	
	@Override
	public List<XeVenStoreDelivView> listDelivByParam(
			StoreDeliveryForm form) {
		
		return deliveryReadMapper.listDelivByParam(form);  
		
	}

	  
	/* 
	 * 查询出库单商品明细 
	 *(non-Javadoc)  
	 * @see com.xebest.web.service.XeVenStoreDelivService#listDelivDetailByParam(java.util.Map)  
	*/  
	
	@Override
	public List<XeVenDelivDetailView> listDelivDetailByParam(
			Map<String, Object> params) {

		return delivDetailReadMapper.listDelivDetail(params);  
	}


	  
	/*  
	 * 进行出库
	 * 现有流程出库时，商品库存是足的，直接添加备货记录
	 *(non-Javadoc)  
	 * @see com.xebest.web.service.XeVenStoreDelivService#saveDeliv(com.xebest.web.model.XeVenStoreDeliveryEntity)  
	*/  
	
	@Override
	@Transactional(value="writeTransactionManager")
	public int saveDeliv(XeVenStoreDeliveryEntity delivEntity) throws Exception {
		log.info("进行出库，出库信息为{}",JSON.toJSONString(delivEntity));
		int result = 0;
		//获取出库单号
		String delivOrder = "";
		if(StringUtils.isEmpty(delivOrder)){
			delivOrder = StoreHouseSeqUtil.seqUtils.createDeliveryOrder();
			log.info("生成出库单号{}",delivOrder);
			delivEntity.setDeliveryOrder(delivOrder);//设置出库单号
		}
		
		//获取出库单商品明细
		List<XeVenStoreDelivDetailEntity> delivDetailList = new ArrayList<XeVenStoreDelivDetailEntity>();
		delivDetailList = delivEntity.getDelivDtailList();
		
		// 如果出库数量为0，不进行出库.如果是销售出库，则更新仓库的订单占用数
		Iterator<XeVenStoreDelivDetailEntity> it=delivDetailList.iterator();
		while(it.hasNext())
        {
			XeVenStoreDelivDetailEntity ddEntity = it.next();
			//要出库的数量
			BigDecimal delivNum = ddEntity.getProOutNum();
			Integer delivType = delivEntity.getDeliveryType();
			BigDecimal zeroNum = new BigDecimal(0);
           if(zeroNum.compareTo(delivNum) == 0)
           {	/*销售出库，如果出库数量为0，则不进行出库操作,释放订单占用*/
        	   if(delivType.equals(VenStoreDeliveryTypeEnum.SALES_DELIVERY.getValue())){
        		   XeVenStoreInventoryEntity invEntity = new XeVenStoreInventoryEntity();
              		invEntity.setUserCode(delivEntity.getUserCode());
              		invEntity.setStoreId(delivEntity.getStoreId());
              		invEntity.setProSku(ddEntity.getProSku());
              		invEntity.setModifyUser(delivEntity.getModifyUser());
              		BigDecimal lockInv = ddEntity.getPlanOutNum().multiply(new BigDecimal(-1));
              		invEntity.setLockedInv(lockInv.setScale(2, BigDecimal.ROUND_HALF_UP));
              		log.info("订单{}销售出库，如果出库数量为0，仓库{}上商品{}，释放订单占用{}",delivEntity.getRelationOrder(),delivEntity.getStoreId(),ddEntity.getProSku(),ddEntity.getPlanOutNum());
              		xeVenStoreInventoryWriteMapper.updateStoreInvByMap(invEntity, null);
   			}
             it.remove();
           }
        }
		
		
		
		//3:轮询出库商品
			//封装查询出库批次详情的参数
		 Map<String,Object> invDetailParamMap = new HashMap<String,Object>();
		 invDetailParamMap.put("userCode", delivEntity.getUserCode());
		 invDetailParamMap.put("storeId", delivEntity.getStoreId());
		 //构造本次出库所有的备货列表
		 List<XeVenStoreStockEntity> storeStockList = new ArrayList<XeVenStoreStockEntity>();
		
		 //循环出库批次详情，进行备货，更新仓库库存商品明细
		for(XeVenStoreDelivDetailEntity delivDetail:delivDetailList){
			//设置出库单商品明细的出库单号
			delivDetail.setDeliverOrder(delivEntity.getDeliveryOrder());
			
			//封装查询出库批次详情的参数
			invDetailParamMap.put("proSku", delivDetail.getProSku());
			//要出库的数量
			BigDecimal delivNum = delivDetail.getProOutNum();
			//用于统计已有的商品库存及商品总额
			BigDecimal hasNum = new BigDecimal(0);
			BigDecimal hasProAmount = new BigDecimal(0);
			//根据userCode,storeId,proSku查询商品的入库批次
			List<XeVenStoreInventoryDetailEntity> invDetailList = invDtailWriteMapper.getInvDetailByMap(invDetailParamMap);
			//循环入库批次,进行备货
			for(XeVenStoreInventoryDetailEntity invDetail:invDetailList){
				BigDecimal actualInv = invDetail.getActualInv();//该批次的实际库存数
				
				hasNum = hasNum.add(actualInv);
				
				//如果批次实际库存大于等于要出库的数量
				if(hasNum.compareTo(delivNum)>=0){
					//添加备货记录
					XeVenStoreStockEntity storeStock = new XeVenStoreStockEntity();
					storeStock.setOrderId(delivEntity.getDeliveryOrder());
					storeStock.setProSku(delivDetail.getProSku());
					storeStock.setStoreId(delivEntity.getStoreId());
					storeStock.setUserCode(delivEntity.getUserCode());
					storeStock.setCreateUser(delivEntity.getCreateUser());
					storeStock.setModifyUser(delivEntity.getModifyUser());
					storeStock.setReceiptBacthNo(invDetail.getBatchNo());
					storeStock.setReceiptBatchPrice(invDetail.getBatchPrice());
					storeStock.setStockNums(delivNum);//批次库存足，备货数为出库数
					BigDecimal perDelivAmount = delivNum.multiply(invDetail.getBatchPrice());
					hasProAmount = hasProAmount.add(perDelivAmount);
					
					storeStockWriteMapper.insertStoreStock(storeStock);
					log.info("====================批次实际库存大于等于要出库的数量时，添加商品备货信息====================");
					storeStockList.add(storeStock);
					hasNum = new BigDecimal(0);
					break;
				} else {//如果该批次库存不足
					//添加备货记录
					XeVenStoreStockEntity storeStock = new XeVenStoreStockEntity();
					storeStock.setOrderId(delivEntity.getDeliveryOrder());
					storeStock.setProSku(delivDetail.getProSku());
					storeStock.setStoreId(delivEntity.getStoreId());
					storeStock.setUserCode(delivEntity.getUserCode());
					storeStock.setCreateUser(delivEntity.getCreateUser());
					storeStock.setModifyUser(delivEntity.getModifyUser());
					storeStock.setReceiptBacthNo(invDetail.getBatchNo());
					storeStock.setReceiptBatchPrice(invDetail.getBatchPrice());
					storeStock.setStockNums(actualInv);//批次库存不足，备货数为该批次的入库数
					
					BigDecimal perDelivAmount = actualInv.multiply(invDetail.getBatchPrice());
					hasProAmount = hasProAmount.add(perDelivAmount);
					storeStockWriteMapper.insertStoreStock(storeStock);
					log.info("====================该批次库存不足时，添加商品备货信息====================");
					storeStockList.add(storeStock);
					continue;
				}
				
				
			}
			
			//计算出库单商品的出库批次价格
			BigDecimal delivBatchPrice = BigDecimalUtil.divideHalfUp(hasProAmount, delivNum, 4);
			delivDetail.setDelivBatchPrice(delivBatchPrice.setScale(2, BigDecimal.ROUND_HALF_UP));
		}
		//根据备货信息更新库存明细
		if(null!=storeStockList && storeStockList.size()>0){
			result = storeInventoryService.updateStoreInvAndDetailByStoreStock(storeStockList, delivEntity.getDeliveryType());
		}
		if(result > 0){
			//添加出库单
			log.info("添加出库单{}，关联单号",delivEntity.getDeliveryOrder(),delivEntity.getRelationOrder());
			result = deliveryWriteMapper.insertStoreDeliv(delivEntity);
			//添加出库单明细
			if(result>0){
				result = delivDetailWriteMapper.batchInsertDelivDetail(delivDetailList);
				log.info("添加出库单明细总数据{}，执行结果{}",delivDetailList.size(),result);
			}
		}
		//根据出库信息更新库存一览
		if(result > 0){
			result = storeInventoryService.updateStoreInvAndDetailByDeliv(delivEntity);
		}
		
		return result;  
		
	}

}
  
